#include "stdlib.h"
#include "stdio.h"
#include "string.h"
#include "object_dict.h"

static int set_entry(struct entry* entry, const void* data_address, enum entry_type type)
{
  
   if(entry->type != type)
   {
       return 0 ;
   }
   else
   {
        switch(type) 
        {
            case ENTRY_FLOAT:
            memcpy((void*)(&entry->float_data), data_address, sizeof(float));
            break;

            case ENTRY_INT:
           
            memcpy((void*)(&entry->int_data), data_address, sizeof(int));

            break;

            case ENTRY_FUNCTION:
            memcpy((void*)(*entry->trigger_function), data_address, sizeof(void*));
            break;
            default:
            return 0;
        }
        return 1;
   }
}

static int get_entry(struct entry* entry,  void* data_address, enum entry_type type)
{
   if(entry->type != type)
   {
       return 0 ;
   }
   else
   {
        switch(type) 
        {
            case ENTRY_FLOAT:
            memcpy(data_address, (void*)(&entry->float_data), sizeof(float));
            break;

            case ENTRY_INT:
            memcpy(data_address, (void*)(&entry->int_data), sizeof(int));
            break;

            case ENTRY_FUNCTION:
            memcpy(data_address, (void*)(&entry->trigger_function), sizeof(void*));
            break;
            default:
            return 0;
        }
        return 1;
   }
}
int get_dict_entry(struct object_dict* od, int index, void* data_address, enum entry_type type)
{
    int revalue = 0;
    if(od == NULL)
    {
        return revalue;
    }
    if( index > ENTRY_MAX_NUMBER || index<0)
    {
        return  revalue;
    }
    revalue = get_entry(od->entry_array + index , data_address, type);
    return revalue ;
}

int call_dict_entry(struct object_dict* od, int index)
{
    int revalue = 0;
    if(od == NULL)
    {
        return revalue;
    }
    if( index > ENTRY_MAX_NUMBER || index<=0)
    {
        return  revalue;
    }
    if(od->entry_array[index].type != ENTRY_FUNCTION)
    {
        return  revalue;
    }
    od->entry_array[index].trigger_function();
    return 1 ;
}
int set_dict_entry(struct object_dict* od, int index, const void* data_address, enum entry_type type)
{
    int revalue = 0;
    if(od == NULL)
    {
        return revalue;
    }
    if( index > ENTRY_MAX_NUMBER || index<0)
    {
        return  revalue;
    }
    revalue = set_entry(od->entry_array + index , data_address, type);
    return revalue ;
}

int show_entry(const struct entry* en)
{
    printf("|index:%d",en->index);
    switch(en->type)
    {
        case ENTRY_IDEL:
        printf("|type:idel");
        printf("|data:%d",en->int_data);
        printf("\n");
        break;
        case ENTRY_INT:
        printf("|type:int");
        printf("|data:%d",en->int_data);
        printf("\n");
        break;
        case ENTRY_FLOAT:
        printf("|type:float");
        printf("|data:%f",en->float_data);
        printf("\n");
        break;
        case ENTRY_FUNCTION:
        printf("|type:function");
        printf("|data:%x",en->trigger_function);
        printf("\n");
        break;
        default:
        return 0;
    }
    return 1;
}
int show_dict(const struct object_dict* od)
{
    int i = 0;
    if(od!=NULL)
    {
        printf("device_id:%d\n",od->can_id);
        
        for(; i<ENTRY_MAX_NUMBER; i++)
        {
            show_entry(od->entry_array + i);
        }
        return 1;
    }
    else
    {
        return 0;
    }
}

enum entry_type get_entry_type(const struct object_dict* od, int index)
{
    return  od->entry_array[index].type;
}

void set_dict_id( struct object_dict* od, int id)
{
    od->can_id = id;
}

